/* 新生命周期函数
废弃了如下3个
will mount
will receive props
will update
*/
import React, {Component} from 'react';
import ReactDOM from 'react-dom';

interface Props {
}

interface State {
  number: number
}

//getDerivedStateFromProps
class Counter extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {number: 0}
  }

  handleClick = () => {
    this.setState({number: this.state.number + 1});
  };

  render() {
    return (
      <div>
        <p>{this.state.number}</p>
        <button onClick={this.handleClick}>+</button>
        <hr/>
        <ChildCounter n={this.state.number}/>
      </div>
    )
  }
}

interface ChildCounterProps {
  n: number
}

interface ChildCounterState {
  number: number
}

class ChildCounter extends Component<ChildCounterProps> {
  state = {number: 0};

  /*componentWillReceiveProps() {//已经废弃，取而代之的就是getDerivedStateFromProps

  }*/

  //从新的属性中派生出新的状态
  //把属性映射为新的状态 ,它返回的就是新的状态对象
  //和废弃的will receive props不一样，初始化时就会执行
  //设计为static 是为了 防止你在这里 this.setState 导致死循环
  static getDerivedStateFromProps(nextProps: ChildCounterProps, prevState: ChildCounterState) {
    console.log('getDerivedStateFromProps prevState:', prevState); //这个state是整个状态树 {number: 0}
    // this.setState(prevState) //TS2339: Property 'setState' does not exist on type 'typeof ChildCounter'.  //typeof 一个class 取的是这个class本身的类型额而不是实例的类型 , So 这就说明我们的类上确实没有setState方法 , 只有实例上才有

    const {n} = nextProps;
    if (n % 2 === 0) {
      return {number: n * 2}; //返回的状态会自动合并
    } else {
      return {number: n * 3};
    }
    //return null; //返回null的话 就什么都不会做(也不会改变现有的state)
  }

  shouldComponentUpdate(nextProps: any, nextState: any, nextContext: any): boolean {
    console.log('this.state.number:', this.state.number); //等于上面的prevState
    console.log('nextProps:', nextProps); //1
    console.log('nextState:', nextState); //3
    console.log('nextContext:', nextContext);
    return this.state.number % 2 === 0;
  }

  //render是把创建的react组件转换成真实的dom元素
  //render是一个函数，它把react组件转成虚拟DOM元素
  //react-dom负责把虚拟DOM变成真实DOM
  render() {
    //return React.createElement('div',null,this.state.number)
    //{type:'div',props:{children:this.state.number}}
    return (<div>
      {this.state.number}
    </div>)
  }
}

ReactDOM.render(<Counter/>, document.getElementById('root'));
